You can specialize the three generic comparison functions listed below by specifying method definitions in your class. These generic functions take two arguments, self and another object, and return true
or false
.
nextMethod
to call the original definitions of these functions from within your definition.isComparable
generic function returns either true
or false
, depending on whether the objects (and they must be objects, not classes) can be compared. By default, isComparable
returns true
if each argument is of the same class.(getClass self) = (getClass anotherObject)
However, some objects may be comparable even though they are not instances of the same class. For example, numbers are generally comparable. Instances of Number
are comparable because each number class defines its own versions of isComparable
, localLt
, and localEqual
. If you define a new class, you might want to specialize these three methods in your class so that instances of other classes can be compared with instances of your class.
method isComparable self other -> (
if ((nextMethod self other) == true) or \
(isAKindOf self MySuperClass)
then return true
else return false
)
method isComparable self other -> (
if ((allIvNames other) contains @target)
then return true
else return false
)
localLt
and localEqual
generic functions are used by their functional equivalents, lt
and equal
( <
and =
) to specify whether one object is less than or equal to another in value. They are also used as the basis for many of the other comparison functions, such as cmp
, le
, ge
, and gt
.
Both localLt
and localEqual
generally assume that their arguments are comparable, that is, that isComparable
returns true
.
When redefining localLt
and localEqual
, be careful not to actually call any comparison functions or operators to compare those same arguments. Because those functions use the methods you are now defining, you can create a circular method call by doing this. For example, do not do this:
method localEqual self other -> (
if (self = other)
then return true
else return false
)
Note that the test, self = other
, uses the equal
function, which then uses localEqual
to test its arguments. However, you've just redefined localEqual
to test the arguments using equal
, and so on.
You can avoid this circularity by using nextMethod
to compare the objects, or to compare parts of those objects. For example, you might compare the values of instance variables:
method localLt self other -> (
if (isComparable self other)
then if ((nextMethod self other) == true) and \
(((size self) < (size other)) == true)
then return true
else return false
)
else (report Unordered #(self, other))For more information about comparison functions and the ScriptX Comparison protocol, see the chapter "Object System Kernel" in the ScriptX Components Guide.
This document is part of the ScriptX Language Guide, one of the volumes of the ScriptX Technical Reference Series. ScriptX is developed by the ScriptX Engineering Team at Apple Computer, successor to the Kaleida Engineering Team at Kaleida Labs, Inc.